#pragma once
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
class ExternalBallisticsSimulator {
   public:
    ExternalBallisticsSimulator(){};

    //直接传所有参数的构造函数
    ExternalBallisticsSimulator(float shellMass, float muzzleVelocity, float dragCoefficient, float caliber,
                                float AirDensity, float G) {
        m_shellMass = 0.001 * static_cast<double>(shellMass);
        m_muzzleVelocity = static_cast<double>(muzzleVelocity);
        m_dragCoefficient = static_cast<double>(dragCoefficient);
        m_caliber = 0.001 * static_cast<double>(caliber);
        m_AirDensity = static_cast<double>(AirDensity);
        m_G = static_cast<double>(G);

        m_shellarea = 3.14159 * (m_caliber / 2) * (m_caliber / 2);
    }

    double m_timeStep = 0.0005;  //模拟的时间粒度为0.5ms
    // int m_outputInterval = 100;   //默认每隔100步输出一次

    //以下为静态量
    double m_shellMass = 0.001;                      //弹头质量
    double m_muzzleVelocity;                         //初速
    double m_dragCoefficient;                        //空气阻力系数
    double m_caliber = 0.013;                        //口径，默认13mm
    double m_shellarea = 0.0065 * 0.0065 * 3.14159;  //弹头面积
    double m_AirDensity = 1.24;                      // 10摄氏度时的空气密度
    double m_G = 9.8;                                //重力加速度

    //以下为动态量
    double m_shellHorizontalPosition;  //弹头水平位置
    double m_shellVerticalPosition;    //弹头垂直位置

    double m_shellHorizontalVelocity;  //弹头水平速度
    double m_shellVerticalVelocity;    //弹头垂直速度

    double m_shellHorizontalAcceleration;  //弹头水平加速度
    double m_shellVerticalAcceleration;    //弹头垂直加速度

    double m_shellHorizontalForce;  //弹头水平受力
    double m_shellVerticalForce;    //弹头垂直受力

    //函数
    void initialize();
    void initializefromyaml(const std::string& Filepath);

    void initializeall(float shellMass, float muzzleVelocity, float dragCoefficient, float caliber, float AirDensity,
                       float G);

    void stateinitialize();

    void computeForces();
    void computeAcceleration();
    void computeVelocity();
    void computePosition();

    std::string outputData(int step);
    std::string runSim();
};
